﻿using System;
using System.Linq;
using System.Reflection;
using System.Web.UI;
using System.Web.UI.WebControls;
using Infragistics.Web.UI.EditorControls;

namespace AresCustomYacht
{
    public static class ReflectionCopier<T> where T : class, new()
    {

        public static T Copy(object source, object destination)
        {


            var sourceProperties = source.GetType().GetProperties();

            var targetProperties = destination.GetType().GetProperties();

            var properties = (from s in sourceProperties
                              from t in targetProperties
                              where s.Name == t.Name &&
                                    s.CanRead &&
                                    t.CanWrite &&
                                    s.PropertyType.IsPublic &&
                                    t.PropertyType.IsPublic &&
                                    s.PropertyType == t.PropertyType &&
                                    (
                                        (s.PropertyType.IsValueType && t.PropertyType.IsValueType)
                                        || (s.PropertyType == typeof (string) && t.PropertyType == typeof (string)
                                           )
                                    )
                              select new PropertyMap
                                         {
                                             SourceProperty = s,
                                             TargetProperty = t
                                         }).ToList();


            foreach (var prop in properties)
            {

                PropertyInfo sourceProp = source.GetType().GetProperty(prop.SourceProperty.Name);
                PropertyInfo destProp = destination.GetType().GetProperty(prop.SourceProperty.Name);
                destProp.SetValue(destination, sourceProp.GetValue(source, null), null);
            }

            return (T) destination;

        }

        public static T Copy(object source)
        {


            var sourceProperties = source.GetType().GetProperties();
            var destination = new T();
            var targetProperties = destination.GetType().GetProperties();

            var properties = (from s in sourceProperties
                              from t in targetProperties
                              where s.Name == t.Name &&
                                    s.CanRead &&
                                    t.CanWrite &&
                                    s.PropertyType.IsPublic &&
                                    t.PropertyType.IsPublic &&
                                    s.PropertyType == t.PropertyType &&
                                    (
                                        (s.PropertyType.IsValueType && t.PropertyType.IsValueType)
                                        || (s.PropertyType == typeof (string) && t.PropertyType == typeof (string)
                                           )
                                    )
                              select new PropertyMap
                                         {
                                             SourceProperty = s,
                                             TargetProperty = t
                                         }).ToList();


            foreach (var prop in properties)
            {

                PropertyInfo sourceProp = source.GetType().GetProperty(prop.SourceProperty.Name);
                PropertyInfo destProp = destination.GetType().GetProperty(prop.SourceProperty.Name);
                destProp.SetValue(destination, sourceProp.GetValue(source, null), null);
            }

            return destination;

        }



        public static void CopyObjectToControls(T obj, Control container)
        {
            if (obj == null) return;
            Type objType = obj.GetType();
            PropertyInfo[] objPropertiesArray = objType.GetProperties();

            foreach (PropertyInfo objProperty in objPropertiesArray)
            {

                Control control = container.FindControl("dfs" + objProperty.Name);
                if (control != null)
                {

                    if (control is TextBox)
                    {
                        var value = objProperty.GetValue(obj, null);
                        if (value != null) ((TextBox)control).Text = value.ToString();
                    }
                    if (control is WebMaskEditor)
                    {
                        var value = objProperty.GetValue(obj, null);
                        if (value != null) ((WebMaskEditor)control).Value = value.ToString();
                    }
                }

                control = container.FindControl("dfm" + objProperty.Name);
                if (control != null)
                {

                    if (control is WebCurrencyEditor)
                    {
                        var value = objProperty.GetValue(obj, null);
                        if (value != null) ((WebCurrencyEditor)control).ValueDecimal = (decimal) value;
                    }

                    if (control is WebNumericEditor)
                    {
                        var value = objProperty.GetValue(obj, null);
                        if (value != null) ((WebNumericEditor)control).ValueDecimal = Convert.ToDecimal(value);
                    }

                }

                control = container.FindControl("dfn" + objProperty.Name);
                if (control != null)
                {

                    if (control is WebNumericEditor)
                    {
                        var value = objProperty.GetValue(obj, null);
                        if (value != null) ((WebNumericEditor)control).ValueInt = Convert.ToInt16(value);
                    }

                    if (control is TextBox)
                    {
                        var value = objProperty.GetValue(obj, null);
                        if (value != null) ((TextBox)control).Text = value.ToString();
                    }
                }


                control = container.FindControl("dfc" + objProperty.Name);
                if (control != null)
                {

                    if (control is DropDownList)
                    {
                        var value = objProperty.GetValue(obj, null);
                        if (value != null) ((DropDownList)control).Text = value.ToString();
                    }
                }

                 control = container.FindControl("dfd" + objProperty.Name);
                if (control != null)
                {
                    if (control is WebDatePicker)
                    {
                        var value = objProperty.GetValue(obj, null);
                        if (value != null && ((DateTime) value) > new DateTime(1900,1,1))
                            ((WebDatePicker)control).Value = value.ToString();
                    }


                }
                control = container.FindControl("dff" + objProperty.Name);
                if (control != null)
                {
                    if (control is CheckBox)
                    {
                        var value = objProperty.GetValue(obj, null);
                        if (value != null )
                            ((CheckBox)control).Checked = (bool)value;
                    }
                }

                control = container.FindControl("dfp" + objProperty.Name);
                if (control != null)
                {
                    if (control is WebPercentEditor)
                    {
                        var value = objProperty.GetValue(obj, null);
                        if (value != null)
                            ((WebPercentEditor)control).ValueDecimal = (Decimal)value;
                    }
                }

            }
        }

        public static void CopyControlsToObject(T obj, Control container)
        {
            Type objType = obj.GetType();
            PropertyInfo[] objPropertiesArray = objType.GetProperties();

            foreach (PropertyInfo objProperty in objPropertiesArray)
            {

                //find matching control
                     Control control = container.FindControl("dfs" + objProperty.Name);
                     if (control != null && objProperty.PropertyType.Name == "String")
                     { //Read control value into the object
                         if (control is TextBox)
                         objProperty.SetValue(obj,
                                      (object) ((TextBox) control).Text, null);

                         if (control is WebMaskEditor)
                             objProperty.SetValue(obj,(object)((WebMaskEditor)control).Text, null);
                     }

                      control = container.FindControl("dfc" + objProperty.Name);
                     if (control != null && objProperty.PropertyType.Name == "String")
                     { //Read control value into the object
                         objProperty.SetValue(obj,
                                      (object)((DropDownList)control).Text, null);
                     }
                     control = container.FindControl("dfm" + objProperty.Name);
                     if (control != null && control is WebCurrencyEditor && (objProperty.PropertyType.FullName.Contains("System.Decimal") ))
                     { //Read control value into the object
                         objProperty.SetValue(obj,
                                      (object)((WebCurrencyEditor)control).ValueDecimal, null);
                     }
                     control = container.FindControl("dfn" + objProperty.Name);
                     if (control != null && control is WebNumericEditor && (objProperty.PropertyType.FullName.Contains("System.Int")))
                     { //Read control value into the object
                         objProperty.SetValue(obj,
                                      (object)((WebNumericEditor)control).ValueInt, null);
                     }

                     if (control != null && control is WebNumericEditor && (objProperty.PropertyType.FullName.Contains("System.Decimal")))
                     { //Read control value into the object
                         objProperty.SetValue(obj,
                                      (object)((WebNumericEditor)control).ValueDecimal, null);
                     }
                     control = container.FindControl("dff" + objProperty.Name);
                     if (control != null && objProperty.PropertyType.FullName.Contains("Boolean"))
                     { //Read control value into the object
                         objProperty.SetValue(obj,
                                      (object)((CheckBox)control).Checked, null);
                     }

                     control = container.FindControl("dfp" + objProperty.Name);
                     if (control != null && objProperty.PropertyType.FullName.Contains("Decimal"))
                     { //Read control value into the object
                         objProperty.SetValue(obj,
                                      (object)((WebPercentEditor)control).ValueDecimal, null);
                     }

                     control = container.FindControl("dfd" + objProperty.Name);
                     if (control != null && objProperty.PropertyType.FullName.Contains("DateTime"))
                     {
                         //Read control value into the object
                         if (control is WebDatePicker)
                         {
                             var value = ((WebDatePicker) control).Value;
                             if (value == null || ((DateTime) value) <= DateTime.MinValue)
                             {
                                 objProperty.SetValue(obj,
                                                      (object) new DateTime(1900, 1, 1), null);
                             }
                             else
                             {
                                 objProperty.SetValue(obj,
                                                      (object) ((WebDatePicker) control).Value, null);
                             }
                         }


                     }
            }
        }
    }




    public class PropertyMap
    {
        public PropertyInfo SourceProperty { get; set; }
        public PropertyInfo TargetProperty { get; set; }
    }
}